package com.hotel.BL;

import java.util.ArrayList;
import java.util.List;

import com.EntityName;
import com.StatusTitle;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;

import data.PayType;
import data.passingData.PayTypeData;

public class PayTypeLogic extends AbstractBL{
	public List<PayType> GeneratePayType(long hotelId)
	{
		List<PayType> list = new ArrayList<PayType>();
		MasterCreator master = new MasterCreator();
		
		PayType paytype;
		if(GetPayType2(hotelId,"Cash")==null){
			paytype= new PayType();
			paytype.setHotelId(hotelId);
			paytype.setDescription("Cash");
			paytype.setMode(master.GetPayModeMaster(StatusTitle.PayModeTitle.Cash));
			paytype.setTitle("Cash");
			paytype.setAvaliable(true);
			paytype.setStatus(true);
			list.add(paytype);
		}
		if(GetPayType2(hotelId,"Credit Card")==null){
			paytype = new PayType();
			paytype.setHotelId(hotelId);
			paytype.setDescription("CreditCard");
			paytype.setMode(master.GetPayModeMaster(StatusTitle.PayModeTitle.CreditCard));
			paytype.setTitle("Credit Card");
			paytype.setAvaliable(true);
			paytype.setStatus(true);
			list.add(paytype);
		}
		if(GetPayType2(hotelId,"Online Payment Gateway")==null){
			paytype = new PayType();
			paytype.setHotelId(hotelId);
			paytype.setDescription("Online Payment Gateway");
			paytype.setMode(master.GetPayModeMaster(StatusTitle.PayModeTitle.CreditCard));
			paytype.setTitle("Online Payment Gateway");
			paytype.setAvaliable(true);
			paytype.setStatus(true);
			list.add(paytype);
		}
		if(GetPayType2(hotelId,"Complimentary")==null){
			paytype = new PayType();
			paytype.setHotelId(hotelId);
			paytype.setDescription("Complimentary");
			paytype.setMode(master.GetPayModeMaster(StatusTitle.PayModeTitle.RevenueLoss));
			paytype.setTitle("Complimentary");
			paytype.setAvaliable(true);
			paytype.setStatus(true);
			list.add(paytype);
		}
		if(GetPayType2(hotelId,"TMB account for agoda transfer")==null){
			paytype = new PayType();
			paytype.setHotelId(hotelId);
			paytype.setDescription("Agoda");
			paytype.setMode(master.GetPayModeMaster(StatusTitle.PayModeTitle.BankTransfer));
			paytype.setTitle("TMB account for agoda transfer");
			paytype.setAvaliable(true);
			paytype.setStatus(true);
			list.add(paytype);
		}
		
		return list;
	}
	
	
	public PayType GetPayType(long l)
	{
		Key key = KeyFactory.createKey(EntityName.PayType, l);
		try {
			Entity lang = datastore.get(key);
			PayType c = new PayType();
			c.setEntity(lang);
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
	}
		
	public PayType GetPayType2(long hotelId,String title)
	{
		Query q = new Query(EntityName.PayType);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterStatus = new FilterPredicate("Status",FilterOperator.EQUAL,true);
		Filter filterAvaliable = new FilterPredicate("Avaliable",FilterOperator.EQUAL,true);
		Filter filterTitle = new FilterPredicate("title",FilterOperator.EQUAL,title);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterStatus, filterAvaliable,filterTitle);
		
		q.setFilter(filter);
		
		return GetPayType(datastore.prepare(q).asSingleEntity());
	}
	

	public List<PayType> GetPayType(long hotelId,String mode)
	{
		Query q = new Query(EntityName.PayType);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterStatus = new FilterPredicate("Status",FilterOperator.EQUAL,true);
		Filter filterAvaliable = new FilterPredicate("Avaliable",FilterOperator.EQUAL,true);
		Filter filterTitle = new FilterPredicate("Mode",FilterOperator.EQUAL,mode);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterStatus, filterAvaliable,filterTitle);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withDefaults()));
	}
	
	public List<PayType> GetAllPayType(long hotelId)
	{
		Query q = new Query(EntityName.PayType);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterStatus = new FilterPredicate("Status",FilterOperator.EQUAL,true);
		Filter filterAvaliable = new FilterPredicate("Avaliable",FilterOperator.EQUAL,true);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterStatus, filterAvaliable);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withDefaults()));
	}
	
	public PayType GetPayType(Entity entity)
	{
		if(entity == null) return null;
		PayType item = new PayType();
		item.setEntity(entity);
		return item;
	}
	
	public List<PayType> GetList(List<Entity> entities)
	{
		List<PayType> list = new ArrayList<PayType>();
		for(Entity e : entities)
		{
			PayType a = new PayType();
			a.setEntity(e);
			list.add(a);
		}
		return list;
	}

	public PayType AddPayType(long hotelId,String title,long mode,String description) throws EntityNotFoundException{
		PayType t = new PayType();
		MasterCreator master = new MasterCreator();
		t.setHotelId(hotelId);
		t.setTitle(title);
		t.setMode(master.GetPayModeMaster(mode));
		t.setDescription(description);
		t.setAvaliable(true);
		t.setStatus(true);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public PayType EditPayType(long paytypeId,String title,long mode,String description) throws EntityNotFoundException{
		PayType t = GetPayType(paytypeId);
		MasterCreator master = new MasterCreator();
		t.setTitle(title);
		t.setMode(master.GetPayModeMaster(mode));
		t.setDescription(description);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public PayType DeletePayType(long payTypeId) throws EntityNotFoundException{
		PayType t = GetPayType(payTypeId);
		t.setAvaliable(false);
		t.setStatus(false);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public PayType ChangeStatus(long payTypeId) throws EntityNotFoundException{
		
		PayType a = GetPayType(payTypeId);
		if(a.isStatus() == true){
			a.setStatus(false);
		}else if(a.isStatus() == false){
			a.setStatus(true);
		}
		 
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);

		return a;
	}
	
	public PayType UpdatePayType(PayType p)
	{
		Key key = datastore.put(p.getEntity());
		p.setId(key.getId());
		p.setKey(key);
		return p;
	}

	public List<PayTypeData> GetAllPayType4AdminLimit(long hotelId,long offset,long line)
	{
		Query q = new Query(EntityName.PayType);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("Avaliable",FilterOperator.EQUAL,true);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable);
		
		q.setFilter(filter);
		
		return ReturnData(GetList(datastore.prepare(q).asList(FetchOptions.Builder.withLimit((int) line).offset((int)offset))));
	}	
	
	public List<PayTypeData> ReturnData(List<PayType> list){
		List<PayTypeData> data = new ArrayList<PayTypeData>();
		for(int i=0;i<list.size();i++){
			PayTypeData x = new PayTypeData();
			x.setDescription(list.get(i).getDescription());
			x.setId(list.get(i).getId());
			x.setMode(list.get(i).getMode().getTitle());
			x.setStatus(list.get(i).isStatus());
			x.setTitle(list.get(i).getTitle());
			data.add(x);
		}
		return data;
	}
	
	public List<PayType> GetAllPayType4Admin(long hotelId)
	{
		Query q = new Query(EntityName.PayType);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("Avaliable",FilterOperator.EQUAL,true);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withDefaults()));
	}
}
